<?php

class Default_Plugin_User extends Zend_Controller_Plugin_Abstract
{

	protected static $acls = array();

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
		$auth = Zend_Auth::getInstance();
		$user = $auth->getIdentity();
		$role = $user ? $user['role'] : 'guest';
		$acl = $this->_getAcl($request->getModuleName());
		if ($acl)
		{
			$resource = $request->getControllerName();
			$privilege = $request->getActionName();
			if (
				!$acl->hasRole($role) ||
				!$acl->has($resource) ||
				!$acl->isAllowed($role, $resource, $privilege)
			)
			{
				$request->setControllerName('index');
				$request->setActionName('login');
			}
		}
		Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($acl);
		Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole($role);
		Zend_Registry::set('user', $user);
	}

	protected function _getAcl($module)
	{
		$filename = "modules/{$module}/configs/acl.ini";
		if (isset(self::$acls[$module]))
		{
			$acl = self::$acls[$module];
		}
		elseif(is_readable($filename))
		{
			$acl = new Zend_Acl();
			$config = new Zend_Config_Ini($filename);
			foreach ($config->roles->toArray() as $role=>$parent)
			{
				$acl->addRole(new Zend_Acl_Role($role), !empty($parent) ? $parent : null);
			}
			foreach ($config->allow->toArray() as $resource=>$privileges)
			{
				if ($resource != 'all' && !$acl->has($resource))
				{
					$acl->addResource(new Zend_Acl_Resource($resource));
				}
				foreach ($privileges as $privilege=>$role)
				{
					$acl->allow($role,
						$resource != 'all' ? $resource : null,
						$privilege != 'all' ? $privilege : null
					);
				}
			}
			foreach ($config->deny->toArray() as $resource=>$privileges)
			{
				if (!$acl->has($resource))
				{
					$acl->addResource(new Zend_Acl_Resource($resource));
				}
				foreach ($privileges as $privilege=>$role)
				{
					$acl->deny($role,
						$resource != 'all' ? $resource : null,
						$privilege != 'all' ? $privilege : null
					);
				}
			}
			self::$acls[$module] = $acl;
		}
		else
		{
			$acl = null;
		}
		return $acl;
	}

}
